//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;

namespace OpenLS.Core.Serialization
{
    public partial class ReadContext
    {
        private T getOptionalEnumWithNamespace<T>(string name, string namespaceUri, T defaultValue) where T : struct
        {
            T? result = getOptionalEnumWithNamespace<T>(name, namespaceUri);
            if (result == null)
                return defaultValue;
            return result.Value;
        }


        public DateTime GetDate(string attributeName)
        {
            return XmlConvert.ToDateTime(GetString(attributeName), XmlDateTimeSerializationMode.Utc);
        }

        public string ReadOptionalElementStringAttribute(string elementName)
        {
            return ReadOptionalElementStringAttribute(elementName, "val");
        }

        public RelatedReadContext GetRelatedContext(string relationshipType, string namespaceUri, bool forceNamespace)
        {
            RelatedReadContext result = GetRelatedContext(relationshipType, namespaceUri);
            if (result != null)
                result._forceNamespace = forceNamespace;
            return result;
        }

        public IEnumerable<T> ReadElements<T>(string elementName) where T : IOfficeXmlSerializableAs, new()
        {
            while (ReaderLocalName == elementName)
            {
                var t = new T();
                t.ReadXmlAs(elementName, this);
                yield return t;
            }
        }

        #region Nested type: EnumConverter

        private class EnumConverter
        {
            private readonly Dictionary<Type, Dictionary<string, object>> _map =
                new Dictionary<Type, Dictionary<string, object>>();

            public T GetValue<T>(string s)
            {
                if (s == null)
                    return default(T);
                if (!_map.ContainsKey(typeof (T)))
                {
                    var m = new Dictionary<string, object>();
                    foreach (FieldInfo f in (typeof (T).GetFields(BindingFlags.Public | BindingFlags.Static)))
                    {
                        string name = f.Name;
                        foreach (XmlEnumAttribute a in f.GetCustomAttributes(typeof (XmlEnumAttribute), false))
                            name = a.Name;
                        m[name] = f.GetValue(null);
                    }
                    _map[typeof (T)] = m;
                }
                var map = _map[typeof (T)];
                if (!map.ContainsKey(s))
                    s = s.ToLower();
                return (T) _map[typeof (T)][s];
            }
        }

        #endregion
    }
}